package com.tuanzi.loan.workflow.repository.impl;

import static com.tuanzi.loan.generated.jooq.loan.tables.ActExtTodoReadlog.ACT_EXT_TODO_READLOG;
import static com.tuanzi.loan.generated.jooq.loan.tables.ActHiProcinst.ACT_HI_PROCINST;
import static com.tuanzi.loan.generated.jooq.loan.tables.ActReProcdef.ACT_RE_PROCDEF;
import static com.tuanzi.loan.generated.jooq.loan.tables.ActRuTask.ACT_RU_TASK;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSystemUser.LOAN_SYSTEM_USER;

import org.jooq.Record;
import org.jooq.RecordMapper;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import com.google.common.collect.Lists;
import com.tuanzi.loan.core.repository.JOOQBaseRepository;
import com.tuanzi.loan.workflow.repository.custom.RunningTaskRepositoryCustom;
import com.tuanzi.loan.workflow.vo.TaskSearchRequest;
import com.tuanzi.loan.workflow.vo.TaskSearchResponse;

/**
 * @author Ray
 * @date 2018/01/12
 */
public class RunningTaskRepositoryImpl extends JOOQBaseRepository implements RunningTaskRepositoryCustom {

	@Override
	protected TableImpl getTable() {
		return ACT_RU_TASK;
	}

	@Override
	public Page<TaskSearchResponse> listTodoTask(TaskSearchRequest request, Pageable pageable) {
		fields(ACT_RU_TASK.ID_, ACT_RU_TASK.PROC_INST_ID_, ACT_RU_TASK.PROC_DEF_ID_, ACT_RU_TASK.TASK_DEF_KEY_, ACT_RU_TASK.NAME_, ACT_RE_PROCDEF.NAME_, ACT_RE_PROCDEF.CATEGORY_,
				ACT_HI_PROCINST.START_TIME_, ACT_HI_PROCINST.NAME_, ACT_HI_PROCINST.START_USER_ID_, ACT_HI_PROCINST.BUSINESS_KEY_, LOAN_SYSTEM_USER.NAME, ACT_RU_TASK.CREATE_TIME_);

		getCurrentFields().add(DSL.field(DSL.selectCount().from(ACT_EXT_TODO_READLOG).where(ACT_EXT_TODO_READLOG.TASK_ID.eq(ACT_RU_TASK.ID_))
				.and(ACT_EXT_TODO_READLOG.PROC_INST_ID.eq(ACT_RU_TASK.PROC_INST_ID_))).as("HAS_READ_LOG"));

		innerJoin(ACT_RE_PROCDEF, ACT_RU_TASK.PROC_DEF_ID_.eq(ACT_RE_PROCDEF.ID_));
		innerJoin(ACT_HI_PROCINST, ACT_RU_TASK.PROC_INST_ID_.eq(ACT_HI_PROCINST.ID_));
		innerJoin(LOAN_SYSTEM_USER, ACT_HI_PROCINST.START_USER_ID_.eq(LOAN_SYSTEM_USER.ACCOUNT));
		eq(ACT_RU_TASK.ASSIGNEE_, request.getAccount());
		eq(ACT_RE_PROCDEF.CATEGORY_, request.getCategory());
		contains(ACT_RE_PROCDEF.NAME_, request.getProcDefName());
		contains(ACT_HI_PROCINST.NAME_, request.getProcInstName());
		ge(ACT_HI_PROCINST.START_TIME_, request.getProcessInitialStartTime());
		le(ACT_HI_PROCINST.START_TIME_, request.getProcessInitialEndTime());
		orderBy(ACT_RU_TASK.CREATE_TIME_, Sort.Direction.DESC);
		return search(pageable, new TaskSearchResponseRecordMapper());
	}

	@Override
	public Long countUnreadTodoTaskCount(String account) {
		String sql = "SELECT (SELECT count( t1.ID_ ) AS AMOUNT FROM ACT_RU_TASK t1,ACT_RE_PROCDEF t2,ACT_HI_PROCINST t3 WHERE t1.PROC_DEF_ID_ = t2.ID_ AND t1.PROC_INST_ID_ = t3.ID_ AND t1.ASSIGNEE_ = ?) + (SELECT 0 - count( t1.ID_ ) AS AMOUNT FROM ACT_RU_TASK t1,ACT_RE_PROCDEF t2,ACT_HI_PROCINST t3,ACT_EXT_TODO_READLOG t4 WHERE t1.PROC_DEF_ID_ = t2.ID_ AND t1.PROC_INST_ID_ = t3.ID_ AND t1.ID_ = t4.TASK_ID AND t1.ASSIGNEE_ = ?)";
		return dslContext.fetchOne(sql, Lists.newArrayList(account, account).toArray()).into(Long.class);
	}

	private final class TaskSearchResponseRecordMapper implements RecordMapper<Record, TaskSearchResponse> {

		@Override
		public TaskSearchResponse map(Record record) {
			TaskSearchResponse response = new TaskSearchResponse();
			response.setId(record.get(ACT_RU_TASK.ID_));
			response.setProcDefId(record.get(ACT_RU_TASK.PROC_DEF_ID_));
			response.setProcInstId(record.get(ACT_RU_TASK.PROC_INST_ID_));
			response.setTaskDefKey(record.get(ACT_RU_TASK.TASK_DEF_KEY_));
			response.setTaskName(record.get(ACT_RU_TASK.NAME_));
			response.setProcDefName(record.get(ACT_RE_PROCDEF.NAME_));
			response.setProcInstStartTime(record.get(ACT_HI_PROCINST.START_TIME_));
			response.setProcInstName(record.get(ACT_HI_PROCINST.NAME_));
			response.setStartUserId(record.get(ACT_HI_PROCINST.START_USER_ID_));
			response.setBusinessKey(record.get(ACT_HI_PROCINST.BUSINESS_KEY_));
			response.setCategory(record.get(ACT_RE_PROCDEF.CATEGORY_));
			response.setStartUserName(record.get(LOAN_SYSTEM_USER.NAME));
			response.setTaskStartTime(record.get(ACT_RU_TASK.CREATE_TIME_));
			Long hasReadLog = record.get("HAS_READ_LOG", Long.class);
			response.setHasReadLog(hasReadLog > 0);
			return response;
		}
	}
}
